查看原文
其他

R包reshape2,轻松实现长、宽数据表格转换

lingludi 生信宝典 2022-03-28

本文翻译自外文博客,原文链接:https://seananderson.ca/2013/10/19/reshape/

一、reshape2 简介

reshape2是由Hadley Wickham编写的R包,可以轻松地在宽格式(wide-format)和长格式(long-format)之间转换数据。

reshape2R包主要有两个主要的功能:meltcast

  • melt:将wide-format数据“熔化”成long-format数据;

  • cast:获取long-format数据“重铸”成wide-format数据。

这两个命名十分形象,方便记忆,你可以想象成你在处理金属。当你熔化金属成液体滴下时,金属会被拉长(long-format)。如果你把金属它铸成一个模子,它就会变宽(wide-format)。

二、什么是宽表格和长表格

示例数据说明:例子使用内置于R中的空气质量数据集(airquality)。

每个变量单独成一列的为宽数据,例如:

##      ozone      wind     temp ## 1 23.61538 11.622581 65.54839 ## 2 29.44444 10.266667 79.10000 ## 3 59.11538  8.941935 83.90323 ## 4 59.96154  8.793548 83.96774

而长数据中变量的ID没有单独列成一列,而是整合在同一列。

长数据矩阵中一列代表变量类型,另外一列表示对用的变量值。例如:

##    variable     value ## 1     ozone 23.615385 ## 2     ozone 29.444444 ## 3     ozone 59.115385 ## 4     ozone 59.961538 ## 5      wind 11.622581 ## 6      wind 10.266667 ## 7      wind  8.941935 ## 8      wind  8.793548 ## 9      temp 65.548387 ## 10     temp 79.100000 ## 11     temp 83.903226 ## 12     temp 83.967742

这并不表示长数据只有两列,比如我们会记录下每个月每天每个空气指标的值,而每个月的天数不一定相等,所以就会出现第三列记录日期。

一般我们实验记录的数据格式(大多习惯用宽表格记录数据)和我们后期用R绘图所用到的数据格式往往不一样,例如ggplot2plyr,还有大多数建模函数lm()glm()gam()等经常会使用长表格数据来作图,这时用reshape2包来转换实验记录的宽表格数据会十分方便。

Wide- to long-format data: the melt function

例子使用内置于R中的空气质量数据集(airquality)。首先,我们将列名更改为小写方便使用。然后查看一下数据:

names(airquality) <- tolower(names(airquality)) head(airquality)##   ozone solar.r wind temp month day ## 1    41     190  7.4   67     5   1 ## 2    36     118  8.0   72     5   2 ## 3    12     149 12.6   74     5   3 ## 4    18     313 11.5   62     5   4 ## 5    NA      NA 14.3   56     5   5 ## 6    28      NA 14.9   66     5   6

如果我们使用所有默认参数运行melt会发生什么呢?

library(reshape2)     #  首先加载一下reshape2包 aql <- melt(airquality) # 命名取首字母:[a]ir [q]uality [l]ong format head(aql)  # 查看数据前6列 tail(aql)   # 查看数据后6列

每一步返回的结果:

## No id variables; using all as measure variables ## head(aql) ##   variable value ## 1    ozone    41 ## 2    ozone    36 ## 3    ozone    12 ## 4    ozone    18 ## 5    ozone    NA ## 6    ozone    28 ## tail(aql) ##     variable value ## 913      day    25 ## 914      day    26 ## 915      day    27 ## 916      day    28 ## 917      day    29 ## 918      day    30

默认情况下melt会认为全部为数值的每一列都是带有变量的值,包括月份和日期,都合并在了一起,标题行置于variable列,数值置于value列。但是有的时候我们想知道每月里面每一天空气指标臭氧、太阳、风和温度的值,这个时候我们可以设置id.vars=c("")来去除指定的列,只将其他数据做变形。

aql <- melt(airquality, id.vars = c("month", "day")) head(aql)##   month day variable value ## 1     5   1    ozone    41 ## 2     5   2    ozone    36 ## 3     5   3    ozone    12 ## 4     5   4    ozone    18 ## 5     5   5    ozone    NA ## 6     5   6    ozone    28

如果我们想控制长数据中的列名怎么办呢?

aql <- melt(airquality, id.vars = c("month", "day"),  variable.name = "climate_variable",  value.name = "climate_value") head(aql)##   month day climate_variable climate_value ## 1     5   1            ozone            41 ## 2     5   2            ozone            36 ## 3     5   3            ozone            12 ## 4     5   4            ozone            18 ## 5     5   5            ozone            NA ## 6     5   6            ozone            28

Long- to wide-format data: the cast functions

首先使用dcast函数将上面转换后的宽数据转换成长数据。用month + day ~ variable告诉dcast月份和日期是变量,转换成的长数据与原始数据除了变量列的序号不一样,其他都一致。

aql <- melt(airquality, id.vars = c("month", "day")) aqw <- dcast(aql, month + day ~ variable) head(aqw) head(airquality) # original data##   month day ozone solar.r wind temp ## 1     5   1    41     190  7.4   67 ## 2     5   2    36     118  8.0   72 ## 3     5   3    12     149 12.6   74 ## 4     5   4    18     313 11.5   62 ## 5     5   5    NA      NA 14.3   56 ## 6     5   6    28      NA 14.9   66 ## original data ##   ozone solar.r wind temp month day ## 1    41     190  7.4   67     5   1 ## 2    36     118  8.0   72     5   2 ## 3    12     149 12.6   74     5   3 ## 4    18     313 11.5   62     5   4 ## 5    NA      NA 14.3   56     5   5 ## 6    28      NA 14.9   66     5   6

如果你还不明白上面发生了什么,下面我们使用一张图解来展示:

蓝色阴影表示我们想要表示的各个行的ID变量,红色表示想要转换成列名变量名灰色表示要在单元格中填充的数据

易错点

当每个单元格有多个值时(比如我们想以月而不是天来查看空气指标值,而每个月有多个数据),我们可能会犯一个错。

下面来一个错误示范,这次我们不再将day作为变量:

dcast(aql, month ~ variable)##   month ozone solar.r wind temp ## 1     5    31      31   31   31 ## 2     6    30      30   30   30 ## 3     7    31      31   31   31 ## 4     8    31      31   31   31 ## 5     9    30      30   30   30

当我们在R运行上面的命令时,会返回一条提示信息:

## Aggregation function missing: defaulting to length

查看输出数据时发现,每个单元格填充的数据为每个月的记录天数,并非每个测量指标值。当我们转换数据并且每个单元格有多个值时,还需要使用fun.aggregate=告知dcast以什么方式重新组合数据,是平均值(mean)、中位数(median)还是总和(sum)。

下面我们试试以平均值来重新组合数据,并使用参数na.rm=TRUE来删除空值NA。

dcast(aql, month ~ variable, fun.aggregate = mean,  na.rm = TRUE)##   month    ozone  solar.r      wind     temp ## 1     5 23.61538 181.2963 11.622581 65.54839 ## 2     6 29.44444 190.1667 10.266667 79.10000 ## 3     7 59.11538 216.4839  8.941935 83.90323 ## 4     8 59.96154 171.8571  8.793548 83.96774 ## 5     9 31.44828 167.4333 10.180000 76.90000

help

  • 阅读帮助文档:help(package=”reshape2”)

  • 查看reshape2官方网站:http://had.co.nz/reshape/

  • 帮助视频:http://had.co.nz/reshape/french-fries-demo.html

  注:视频为.mov格式,可以用QuickTime打开观看

高颜值在线绘图

在我们的免费高颜值绘图网站也有关于wide formatlong format的展示,具体如下表。不同的图形需要对应的选择或提供数据格式。

长按二维码识别跳转至精美的在线作图网站!

R统计和作图

更多阅读

画图三字经 生信视频 生信系列教程 

心得体会 癌症数据库 Linux Python 

高通量分析 在线画图 测序历史 超级增强子

培训视频 PPT EXCEL 文章写作 ggplot2

海哥组学 可视化套路 基因组浏览器

色彩搭配 图形排版 互作网络

后台回复“生信宝典福利第一波”获取教程合集

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存